package com.ls.stack;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

public class PolandNotation {
    public static void main(String[] args) {
        PolandNotation notation = new PolandNotation();
        //逆波兰表达式
        /*String suffixExpression = "30 4 + 5 * 6 -";
        int calculate = notation.calculate(listString);
        System.out.println(calculate);*/

        String expression = "1 + ( ( 2 + 3 ) * 4 ) - 5";
        List<String> listString = notation.getListString(expression);
        System.out.println(listString);
        List<String> list = notation.parseSuffixExpressionOnList(listString);
        System.out.println(list);
        int calculate = notation.calculate(list);
        System.out.println(calculate);
    }


    public List<String> parseSuffixExpressionOnList(List<String> list) {
        Stack<String> s1 = new Stack<>();
        ArrayList<String> result = new ArrayList<>();
        for (String s : list) {
            if (s.matches("\\d+")) {
                result.add(s);
            } else if ("(".equals(s)) {
                s1.push(s);
            } else if (")".equals(s)) {
                while (!"(".equals(s1.peek())) {
                    result.add(s1.pop());
                }
                s1.pop();//消除栈里左括号
            } else {
                //当s的优先级小于栈顶(栈顶的大) 则栈顶出栈
                while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(s)){
                    result.add(s1.pop());
                }
                s1.push(s);
            }
        }
        //将s1 剩余的压制result
        while (s1.size() != 0){
            result.add(s1.pop());
        }

        return result;
    }


    public List<String> getListString(String suffixExpression) {
        ArrayList<String> list = new ArrayList<>();
        String[] array = suffixExpression.split(" ");
        Collections.addAll(list, array);
        return list;
    }

    public int calculate(List<String> ls) {
        Stack<String> stack = new Stack<>();

        for (String s : ls) {
            if (s.matches("\\d+")) {
                stack.push(s);
            } else {
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;
                if ("+".equals(s)) {
                    res = num1 + num2;
                } else if ("-".equals(s)) {
                    res = num1 - num2;
                } else if ("*".equals(s)) {
                    res = num1 * num2;
                } else if ("/".equals(s)) {
                    res = num1 / num2;
                } else {
                    throw new RuntimeException("error");
                }
                stack.push(res + "");
            }
        }
        return Integer.parseInt(stack.pop());

    }

}

class Operation {
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;


    public static int getValue(String operation) {
        int result = 0;
        switch (operation) {
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
                break;
            case "*":
                result = MUL;
                break;
            case "/":
                result = DIV;
                break;
            default:
                System.out.println("Symbol error");
                break;
        }
        return result;
    }

}
